package cn.edu.xmu.oomall.customer.service;

import cn.edu.xmu.oomall.core.model.VoObject;
import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.customer.model.vo.CustomerRetVo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.oomall.customer.dao.CustomerAccountDao;
import cn.edu.xmu.oomall.customer.model.bo.Customer;
import cn.edu.xmu.oomall.customer.model.po.CustomerPo;
import cn.edu.xmu.oomall.customer.model.vo.ModifyCustomerVo;
import cn.edu.xmu.oomall.customer.model.vo.ModifyPwdVo;
import cn.edu.xmu.oomall.customer.model.vo.ResetPwdVo;
import cn.edu.xmu.privilegegateway.annotation.util.Common;
import cn.edu.xmu.privilegegateway.annotation.util.JwtHelper;
import cn.edu.xmu.privilegegateway.annotation.util.RedisUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Set;
/**
 * @author Jiazhe Yuan
 * @date 2021-12-14 12:36:17
 */
@Service
public class CustomerAccountService {

    @Autowired
    private CustomerAccountDao customerAccountDao;

    @Autowired
    private RedisUtil redisUtil;

    @Value("${customer.login.multiply}")
    private Boolean canMultiplyLogin;

    /**
     * customer登录后的key
     */
    private final static String CUSTOMERKEY = "u_%d";

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject getOwnAccount(Long userId) {
        CustomerPo customerPo = (CustomerPo) customerAccountDao.getOwnAccount(userId).getData();
        CustomerRetVo customerRetVo = Common.cloneVo(customerPo, CustomerRetVo.class);
        return new ReturnObject(customerRetVo);
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject login(String loginUsername, String loginPassword) {
        ReturnObject ret = customerAccountDao.getUserByName(loginUsername);
        if (ret.getCode() != ReturnNo.OK) {
            return ret;
        }

        Customer customer = (Customer) ret.getData();
        if (null == customer || !loginPassword.equals(customer.getPassword())) {
            ret = new ReturnObject(ReturnNo.CUSTOMER_INVALID_ACCOUNT);
            return ret;
        }

        String key = String.format(CUSTOMERKEY, customer.getId());
        String id = customer.getId().toString();
        // 用户信息在redis中留存5分钟
        redisUtil.set(key, id, 5*60L);

        JwtHelper jwtHelper = new JwtHelper();
        String jwt = jwtHelper.createToken(customer.getId(), customer.getUserName(), 0L, 0, 3600);
        ret = new ReturnObject(jwt);
        return ret;
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject logout(Long id) {
        String key = String.format(CUSTOMERKEY, id);
        redisUtil.del(key);
        return new ReturnObject<>(ReturnNo.OK);
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject modifyPassword(ModifyPwdVo modifyPwdVo) {
        return customerAccountDao.modifyPassword(modifyPwdVo);
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject modifyOwnAccount(Long id, Long userId, String userName, ModifyCustomerVo modifyCustomerVo) {
        CustomerPo customerPo = (CustomerPo) customerAccountDao.getCustomerPoById(id).getData();
        if (null == customerPo) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        }
        Customer customer = Common.cloneVo(modifyCustomerVo, Customer.class);
        customer.setId(id);
        Common.setPoModifiedFields(customer, userId, userName);
        ReturnObject returnObject = customerAccountDao.modifyOwnAccount(customer);
        return returnObject;
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject resetPassword(ResetPwdVo resetPwdVo) {
        return customerAccountDao.resetPassword(resetPwdVo);
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject banCustomer(Long id, Long adminId, String adminName) {
        ReturnObject returnObject = customerAccountDao.changeCustomerStatus(id, adminId, adminName, Customer.State.BANNED);
        return returnObject;
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject releaseCustomer(Long id, Long adminId, String adminName) {
        ReturnObject returnObject = customerAccountDao.changeCustomerStatus(id, adminId, adminName, Customer.State.NORMAL);
        return returnObject;
    }
}
